<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" >

<title>FineUICore扩展控件 | 没想好的个人博客</title>

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<!-- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> -->
   <!-- Font Awesome CSS-->
   <link href="https://cdn.bootcss.com/font-awesome/5.13.0/css/all.css" rel="stylesheet">

   <link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/5.7.2/css/all.min.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">

<link rel="shortcut icon" href="https://shixixiyue.gitee.io//favicon.ico?v=1709791195950">
<link rel="stylesheet" href="https://shixixiyue.gitee.io//styles/main.css">



<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
<script src="https://jsd.onmicrosoft.cn/npm/vue/dist/vue.js"></script>


<style>
  .hljs-ln{
    padding-bottom: 1.2rem;
    margin: 0rem !important;
  }
  .hljs-ln td {
    border: none !important;
    padding: 2px 6px !important;
    line-height: 1.2rem;
    font-size: 1rem;
  }
  .hljs-ln tr td:first-child  {
    color: cadetblue;
    border-right: 1px solid !important;
  }
  .hljs-ln tr {
    border: none !important;
  }
</style>

    <meta name="description" content="好久没有做内容了，手痒痒，找个控件说说，放点代码






1. 简介
2. 扩展控件

2.1 继承 Panel
2.2 扩展 UIExtension
2.3 增加方法和属性


3. 完整代码

c#部分
js部分
css部分



..." />
    <meta name="keywords" content="FineUICore" />
  </head>
  <body>
    <div id="app" class="main">

      <div class="sidebar" :class="{ 'full-height': menuVisible }">
  <div class="top-container" data-aos="fade-right">
    <div class="top-header-container">
      <a class="site-title-container" href="https://shixixiyue.gitee.io/">
        <img src="https://shixixiyue.gitee.io//images/avatar.png?v=1709791195950" class="site-logo">
        <h1 class="site-title">没想好的个人博客</h1>
      </a>
      <div class="menu-btn" @click="menuVisible = !menuVisible">
        <div class="line"></div>
      </div>
    </div>
    <div>
      
        
          <a href="https://shixixiyue.gitee.io/" class="site-nav">
            首页
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/4gOKry8Qv/" class="site-nav">
            .Net Core
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/njETBpqXu/" class="site-nav">
            FineUICore
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/XyXyeLOBB" class="site-nav">
            读书笔记
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/TyVX6hfCJ" class="site-nav">
            Vue笔记
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/3Hz2sPtzO/" class="site-nav">
            产品
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/Db1wShB_E" class="site-nav">
            其他
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io/" class="site-nav">
            一一一一一一一一一
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//archives" class="site-nav">
            文章归档
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tags" class="site-nav">
            全部标签
          </a>
        
      
    </div>
  </div>
  <div class="bottom-container" data-aos="flip-up" data-aos-offset="0">
    <div class="social-container">
      
        
      
        
      
        
      
        
      
        
      
    </div>
    <div class="site-description">
      没事啥都说
    </div>
    <div class="site-footer">
      QQ：<a href="tencent://message/?uin=935732994&Site=''&Menu=yes">935732994<a/> <a href="http://beian.miit.gov.cn">京ICP备2024045283号<a/> | <a class="rss" href="https://shixixiyue.gitee.io//atom.xml" target="_blank">RSS</a>
    </div>
  </div>
</div>


      <div class="main-container">
        <div class="content-container" data-aos="fade-up">
          <div class="post-detail">
            <h2 class="post-title">FineUICore扩展控件</h2>
            <div class="post-date">2024-03-07
            
                
                  <a href="https://shixixiyue.gitee.io/tag/njETBpqXu/" class="tag">
                    FineUICore
                  </a>
                
            </div>
            
              <div class="feature-container" style="background-image: url('https://shixixiyue.gitee.io//post-images/fineuicore-kong-jian.png')">
              </div>
            
            <div class="post-content" v-pre>
              <p>好久没有做内容了，手痒痒，找个控件说说，放点代码</p>
<!-- more -->
<p><ul class="markdownIt-TOC">
<li>
<ul>
<li>
<ul>
<li><a href="#1-%E7%AE%80%E4%BB%8B">1. 简介</a></li>
<li><a href="#2-%E6%89%A9%E5%B1%95%E6%8E%A7%E4%BB%B6">2. 扩展控件</a>
<ul>
<li><a href="#21-%E7%BB%A7%E6%89%BF-panel">2.1 继承 Panel</a></li>
<li><a href="#22-%E6%89%A9%E5%B1%95-uiextension">2.2 扩展 UIExtension</a></li>
<li><a href="#23-%E5%A2%9E%E5%8A%A0%E6%96%B9%E6%B3%95%E5%92%8C%E5%B1%9E%E6%80%A7">2.3 增加方法和属性</a></li>
</ul>
</li>
<li><a href="#3-%E5%AE%8C%E6%95%B4%E4%BB%A3%E7%A0%81">3. 完整代码</a>
<ul>
<li><a href="#c%E9%83%A8%E5%88%86">c#部分</a></li>
<li><a href="#js%E9%83%A8%E5%88%86">js部分</a></li>
<li><a href="#css%E9%83%A8%E5%88%86">css部分</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</p>
<h3 id="1-简介">1. 简介</h3>
<p>昨天开发用到了步骤条 Step，长这样：<br>
<img src="https://shixixiyue.gitee.io//post-images/1709780788612.png" alt="" loading="lazy"><br>
代码<br>
<img src="https://shixixiyue.gitee.io//post-images/1709780795078.png" alt="" loading="lazy"></p>
<h3 id="2-扩展控件">2. 扩展控件</h3>
<p>这里的 <code>F.Step</code> 是改造的 Panel 控件，Panel就当是个div，修改了渲染 <code>OnFirstPreRender</code>，抛出了自定义的html和js，就成步骤条了， 那么如何像 <code>F.Panel</code> 那样 写一个前台的控件呢</p>
<h4 id="21-继承-panel">2.1 继承 Panel</h4>
<p>第一步就是继承 <code>FineUICore.Panel </code>，重写 <code>OnFirstPreRender</code> ，首先看一下 FineUICore 自己的 Panel怎么写的</p>
<pre><code>namespace FineUICore;

//
// 摘要:
//     面板控件
public class Panel : CollapsablePanel
{
    //
    // 摘要:
    //     渲染 HTML 之前调用（页面第一次加载或者普通回发）
    protected override void OnFirstPreRender()
    {
        base.OnFirstPreRender();
        string scriptContent = $&quot;var {A()}=new F.Panel({d().ToString()});{GlobalConfig.B()}&quot;;
        AddStartupScript(scriptContent);
    }
}
</code></pre>
<p>这是反编译后的结果，代码很简单，就是 输出了一段js <code>new F.Panel</code> ，所以写的类 Step 只要重写 <code>OnFirstPreRender</code> 就行了</p>
<pre><code>/// &lt;summary&gt;
///
/// &lt;/summary&gt;
public class Step : Panel
{
	/// &lt;summary&gt;
	/// 第一次绘制
	/// &lt;/summary&gt;
	protected override void OnFirstPreRender()
	{
		base.OnFirstPreRender();
	}
}
</code></pre>
<p>还需要一个类 继承 <code>CollapsablePanelExtension</code>，前台的 <code>F.Panel</code> 就是一个 <code>PanelExtension</code> 实例，继承的<code>CollapsablePanelExtension</code>，写法如下</p>
<pre><code>/// &lt;summary&gt;
/// 步骤条控件
/// &lt;/summary&gt;
public class StepExtension : CollapsablePanelExtension&lt;Step, StepExtension&gt;
{
	/// &lt;summary&gt;
	/// 步骤条控件
	/// &lt;/summary&gt;
	private Step _source = null;
	
	/// &lt;summary&gt;
	/// 步骤条控件
	/// &lt;/summary&gt;
	/// &lt;param name=&quot;source&quot;&gt;&lt;/param&gt;
	public StepExtension(Step source) : base(source)
	{
		_source = source;
	}
}
</code></pre>
<h4 id="22-扩展-uiextension">2.2 扩展 UIExtension</h4>
<p>现在 <code>StepExtension</code> 还不能用，我们要再包一下，在cshtml能点出来，需要给 <code>FineUICore.UIExtension</code> 扩展，这里也可以查看 F.Panel 不贴出来了，其实它是一个 <code>IHtmlHelper</code>，像这样</p>
<pre><code>/// &lt;summary&gt;
///
/// &lt;/summary&gt;
/// &lt;param name=&quot;helperr&quot;&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
public static StepExtension Step(this UIExtension&lt;dynamic, dynamic&gt; helperr)
{
	StepExtension r = new StepExtension(new FineUICore.Step());
	return r;
}
</code></pre>
<h4 id="23-增加方法和属性">2.3 增加方法和属性</h4>
<p>到这里 cshtml 就可以点出来了，<code>F.Step()</code> 它继承了Panel的所有属性和方法；<br>
现在可以添加自己的属性了，这里来梳理下，<br>
① 比如我要加一个 StepActive 方法，前端想这么写 <code>F.Setp().StepActive(1)</code>，那其实就是 <code>StepExtension</code> ，给它加个方法就行了 StepActive()，<br>
② <code>StepExtension</code>  中有个实例 <code>_source</code> ，将<code>StepActive</code>的参数值，赋值到实例 <code>_source</code> 中，<br>
③ 最后在<code>OnFirstPreRender</code>进行前台的响应，</p>
<div class="mermaid">
sequenceDiagram
    participant 前台
    participant StepExtension
    participant Step
    前台->>StepExtension: F.Setp().StepActive(1)
    StepExtension->>StepExtension: StepActive(index)
    StepExtension->>Step: _source.index = index
    Step->>前台: OnFirstPreRender(_source.index)
</div>
<pre><code>/// &lt;summary&gt;
/// 步骤条控件
/// &lt;/summary&gt;
public class StepExtension : CollapsablePanelExtension&lt;Step, StepExtension&gt;
{
	/// &lt;summary&gt;
	/// 步骤条控件
	/// &lt;/summary&gt;
	private Step _source = null;
	
	/// &lt;summary&gt;
	/// 步骤条控件
	/// &lt;/summary&gt;
	/// &lt;param name=&quot;source&quot;&gt;&lt;/param&gt;
	public StepExtension(Step source) : base(source)
	{
		_source = source;
	}
	
	/// &lt;summary&gt;
	/// 步骤
	/// &lt;/summary&gt;
	/// &lt;param name=&quot;index&quot;&gt;&lt;/param&gt;
	/// &lt;returns&gt;&lt;/returns&gt;
	public StepExtension StepActive(int index)
	{
		_source.stepActive = index;
		return this;
	}
}
</code></pre>
<pre><code>/// &lt;summary&gt;
///
/// &lt;/summary&gt;
public class Step : Panel
{

	/// &lt;summary&gt;
	/// 当前激活的序号
	/// &lt;/summary&gt;
	private int _stepActive = 0;

	/// &lt;summary&gt;
	/// 当前激活的序号
	/// &lt;/summary&gt;
	public int stepActive
	{
		get { return _stepActive; }
		set
		{
			_stepActive = value;
		}
	}

	/// &lt;summary&gt;
	/// 第一次绘制
	/// &lt;/summary&gt;
	protected override void OnFirstPreRender()
	{
        StringBuilder sb = new StringBuilder();
        sb.Append($&quot;this.stepActive = {stepActive};&quot;);
		this.Listeners.Add(new FineUICore.Listener(&quot;render&quot;, sb.ToString()));
		base.OnFirstPreRender();
	}
}
</code></pre>
<blockquote>
<p>注意这里的<code>OnFirstPreRender</code> 将输出的内容写在了render事件中，因为本身这里的this就是一个panel实例，所以可以这么写，这里还可以设置panel的默认参数</p>
</blockquote>
<h3 id="3-完整代码">3. 完整代码</h3>
<p>剩下就是前端的事了，这里放出完整的代码，</p>
<h4 id="c部分">c#部分</h4>
<pre><code>
	#region Step步骤控件 基于Grid 卡片

	/// &lt;summary&gt;
	/// 步骤条控件
	/// &lt;/summary&gt;
	public class StepExtension : CollapsablePanelExtension&lt;Step, StepExtension&gt;
	{
		/// &lt;summary&gt;
		/// 步骤条控件
		/// &lt;/summary&gt;
		private Step _source = null;

		/// &lt;summary&gt;
		/// 步骤条控件
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;source&quot;&gt;&lt;/param&gt;
		public StepExtension(Step source) : base(source)
		{
			_source = source;

			//默认值
			_source.ShowBorder = false;
			_source.ShowHeader = false;

			//_source.CssClass = &quot;f-step&quot;;

			_source.stepActive = 0;
		}

		/// &lt;summary&gt;
		/// 数据源
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;data&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		public StepExtension DataSource(IEnumerable&lt;StepItem&gt; data)
		{
			_source.DataSource = data;
			return this;
		}

		/// &lt;summary&gt;
		/// 步骤
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;index&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		public StepExtension StepActive(int index)
		{
			_source.stepActive = index;
			return this;
		}

		/// &lt;summary&gt;
		/// 是否显示说明
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;b&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		public StepExtension ShowBody(bool b)
		{
			_source.showBody = b;
			return this;
		}
	}

	/// &lt;summary&gt;
	///
	/// &lt;/summary&gt;
	public class Step : Panel
	{
		/// &lt;summary&gt;
		/// 当前激活的序号
		/// &lt;/summary&gt;
		private int _stepActive = 0;

		/// &lt;summary&gt;
		/// 当前激活的序号
		/// &lt;/summary&gt;
		public int stepActive
		{
			get { return _stepActive; }
			set
			{
				_stepActive = value;
			}
		}

		/// &lt;summary&gt;
		/// 数据源
		/// &lt;/summary&gt;
		public IEnumerable&lt;StepItem&gt; DataSource { get; set; } = new List&lt;StepItem&gt;();

		/// &lt;summary&gt;
		/// 是否显示明细
		/// &lt;/summary&gt;
		public bool showBody { get; set; } = true;

		/// &lt;summary&gt;
		/// 第一次绘制
		/// &lt;para&gt;不能变更的属性在这里&lt;/para&gt;
		/// &lt;/summary&gt;
		protected override void OnFirstPreRender()
		{
			this.CssClass += &quot; f-step&quot;;

			StringBuilder sbel = new StringBuilder();
			sbel.Append($&quot;&lt;ul&gt;&quot;);
			for (int i = 0; i &lt; DataSource.Count(); i++)
			{
				var item = DataSource.ToList()[i];
				sbel.Append($&quot;&lt;li class='f-grid-card-row' data-stepId='{item.Id}'&gt;&quot;);
				sbel.Append($&quot;&lt;div class='f-step-card' data-step='{i}'&gt;&quot;);

				sbel.Append($&quot;&lt;div class='f-step-head'&gt;&quot;);
				sbel.Append($&quot; &lt;div class='f-step-icon'&gt;&quot;);
				sbel.Append($&quot; &lt;div class='f-step-num'&gt;&quot;);
				sbel.Append($&quot;{i + 1}&quot;);
				sbel.Append($&quot; &lt;/div&gt;&quot;);
				sbel.Append($&quot; &lt;div class='f-step-icon-finish f-iconfont-correct'&gt;&quot;);
				sbel.Append($&quot; &lt;/div&gt;&quot;);
				sbel.Append($&quot; &lt;/div&gt;&quot;);
				sbel.Append($&quot; &lt;div class='f-step-line'&gt;&quot;);
				sbel.Append($&quot; &lt;/div&gt;&quot;);
				sbel.Append($&quot;&lt;/div&gt;&quot;);

				sbel.Append($&quot;&lt;div class='f-step-main'&gt;&quot;);
				sbel.Append($&quot; &lt;div class='f-step-title'&gt;&quot;);
				sbel.Append($&quot; {item.Title}&quot;);
				sbel.Append($&quot; &lt;/div&gt;&quot;);
				sbel.Append($&quot; &lt;div class='f-step-des'&gt;&quot;);
				sbel.Append($&quot; {item.TextBody}&quot;);
				sbel.Append($&quot; &lt;/div&gt;&quot;);
				sbel.Append($&quot;&lt;/div&gt;&quot;);

				sbel.Append($&quot;&lt;/div&gt;&quot;);
				sbel.Append($&quot;&lt;/li&gt;&quot;);
			}
			sbel.Append($&quot;&lt;/ul&gt;&quot;);

			this.Content = sbel.ToString();

			StringBuilder sb = new StringBuilder();
			sb.Append($&quot;this.stepActive = {stepActive};&quot;);
			sb.Append($&quot;this.showBody = {showBody.ToString().ToLower()};&quot;);
			sb.Append($&quot;this.data = {JArray.FromObject(DataSource).ToString()};&quot;);
			this.Listeners.Add(new FineUICore.Listener(&quot;render&quot;, sb.ToString()));
			base.OnFirstPreRender();
		}
	}

	/// &lt;summary&gt;
	/// 项 ID可忽略
	/// &lt;/summary&gt;
	public class StepItem
	{
		/// &lt;summary&gt;
		/// ID
		/// &lt;/summary&gt;
		public string Id { get; set; }

		/// &lt;summary&gt;
		/// 标题
		/// &lt;/summary&gt;
		public string Title { get; set; }

		/// &lt;summary&gt;
		/// 内容
		/// &lt;/summary&gt;
		public string TextBody { get; set; }
	}

	#endregion Step步骤控件 基于Grid 卡片

</code></pre>
<h4 id="js部分">js部分</h4>
<pre><code>//Panel控件
if (F.Panel) {
	//步骤条订制
	F.Panel.prototype.__stepActive = -1;
	Object.defineProperty(F.Panel.prototype, &quot;stepActive&quot;, {
		/**
		 * 从0开始
		 * @@param {number} val
		 */
		set(val) {
			//设置当前激活的 序号
			//无效的样式是 f-state-disabled
			//完成的样式是 f-step-finish
			//后面的 f-step-card 无效
			//当前的 f-step-line 无效
			//前面的 f-step-card 完成
			const t = this;
			let el = t.el.find(`.f-step-card[data-step=&quot;${val}&quot;]`);
			//一共几步
			let count = t.el.find(`.f-step-card`).length;
			if (val &lt; 0 || this.__stepActive == val) return;
			while (val &gt; count) {
				val = val - count - 1;
			}
			//重置
			t.el.find(`.f-step-finish`).removeClass(&quot;f-step-finish&quot;);
			t.el.find(`.f-state-disabled`).removeClass(&quot;f-state-disabled&quot;);
			for (let i = val + 1; i &lt; count; i++) {
				let nextel = t.el.find(`.f-step-card[data-step=&quot;${i}&quot;]`);
				nextel.addClass(&quot;f-state-disabled&quot;);
			}
			for (let i = 0; i &lt; val; i++) {
				t.el.find(`.f-step-card[data-step=&quot;${i}&quot;]`).addClass(&quot;f-step-finish&quot;);
			}
			el.find(&quot;.f-step-line&quot;).addClass(&quot;f-state-disabled&quot;);
			this.__stepActive = val;
			this.trigger(&quot;stepChange&quot;, []);
		},
		get() {
			return this.__stepActive;
		}
	});
	//监听 showBody 控制是否显示明细
	F.Panel.prototype.__showBody = true;
	Object.defineProperty(F.Panel.prototype, &quot;showBody&quot;, {
		/**
		 * @@param {boolean} val
		 */
		set(val) {
			const t = this;
			let el = t.el.find(`.f-step-card .f-step-des`);
			if (!val) {
				el.addClass(&quot;f-hidden&quot;);
			} else {
				el.removeClass(&quot;f-hidden&quot;);
			}
			this.__showBody = val;
		},
		get() {
			return this.__showBody;
		}
	});
}
</code></pre>
<h4 id="css部分">css部分</h4>
<pre><code>/*步骤条样式*/
.f-step ul {
	display: flex;
	counter-reset: index;
	padding: 20px;
}

.f-step li.f-grid-card-row {
	transition: all .3s;
	border: none;
	border-bottom: 0px solid;
	border-left: 0px solid;
	border-radius: 0px;
	margin: 0px;
	padding: 0px;
	flex: 1;
	min-width: unset;
	display: inline-block;
	position: relative;
}

.f-step li.f-grid-card-row.f-state-active,
.f-step li.f-grid-card-row.f-grid-row-selected,
.f-step li.f-grid-card-row.f-state-hover {
	background: unset;
	color: unset;
}

.f-step .f-step-card {
	transition: all .3s;
}

.f-step .f-step-head {
	display: flex;
}

/*编号*/
.f-step .f-step-head .f-step-num {
	font-size: 16px;
	line-height: 18px;
	text-align: center;
	height: 20px;
	width: 20px;
	border: 1px solid;
	border-radius: 50%;
}

.f-step .f-step-head .f-step-icon {
	height: 20px;
	width: 20px;
	margin: 0px 10px;
}

/*线*/
.f-step .f-step-line {
	border-top: 2px solid;
	margin: 0px;
	flex: 1;
	margin-top: 8px;
	transition: all .3s;
}

/*最后一个横线不显示*/
.f-step li:last-of-type .f-step-line {
	display: none;
}

/*身子*/
.f-step .f-step-main {
	margin-top: 8px;
	padding: 2px;
}

.f-step .f-step-main .f-step-title {
	font-size: 16px;
	font-weight: 600;
	line-height: 25px;
}

/*完成*/
.f-step .f-step-icon-finish {
	opacity: 0;
	position: absolute;
	transition: opacity .3s;
	display: inline-block;
	font: normal normal normal 16px/1 FontAwesome;
	text-rendering: auto;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-indent: 0;
	min-width: 16px;
	overflow: hidden;
	background-repeat: no-repeat;
	line-height: 20px;
	font-family: &quot;iconfont&quot;;
}

.f-step .f-step-num {
	opacity: 1;
	top: 0px;
	position: absolute;
	transition: all .3s;
}

.f-step .f-step-finish .f-step-num {
	opacity: 0;
	top: -10px;
}

.f-step .f-step-finish .f-step-icon-finish {
	opacity: 1;
}

/*步骤条样式 结束*/
</code></pre>

            </div>
            
              <div class="tag-container">
                
                  <a href="https://shixixiyue.gitee.io/tag/njETBpqXu/" class="tag">
                    FineUICore
                  </a>
                
              </div>
            
            
              <div class="next-post">
                <div class="next">下一篇</div>
                <a href="https://shixixiyue.gitee.io/fineuigrid-dao-chu-tu-pian-de-shi-jian/">
                  <h3 class="post-title">
                    FineUIGrid导出图片的实践
                  </h3>
                </a>
              </div>
            

            

          </div>

        </div>
      </div>
    </div>

    <script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script type="application/javascript">

AOS.init();

var app = new Vue({
  el: '#app',
  data: {
    menuVisible: false,
  },
})

</script>


  <script src="//jsd.onmicrosoft.cn/gh/highlightjs/cdn-release@11.5.1/build/highlight.min.js"></script>
  <script>
    hljs.initHighlightingOnLoad();
    //hljs.registerLanguage('mermaid', window.hljsDefineMermaid);
  </script>
  <script src="//jsd.onmicrosoft.cn/npm/highlightjs-line-numbers.js@2.8.0/dist/highlightjs-line-numbers.min.js"></script>
  <script>
    hljs.initLineNumbersOnLoad({
      singleLine: true
    });
  </script>
 <script src="https://jsd.onmicrosoft.cn/npm/mermaid/dist/mermaid.min.js"></script>
   <script>
    mermaid.initialize({
      startOnLoad: true,
      securityLevel: 'loose',
    });
  </script>





  </body>
</html>
